////////////////////////////////////////////////////////
// CodePlex - metacpp
//--------------------
// This file is part of "metacpp" project on CodePlex. The
// goal if the project is to demonstrate basic techniques
// used in C++ metaprogrammins.
// For more info and comments please visit:
// http://www.codeplex.com/metacpp/
////////////////////////////////////////////////////////

#include <iostream>

/////////////////////////////////////////
// DETECT CONVERTIBILITY
//
// wonders of "sizeof"!!!

template<class T, class U>
class Conversion {
	// first of all, we have to define 2 types of *different* size
	typedef char Small;
	class Big { char dummy[2]; };

	// now we define 2 versions of function Test
	static Small Test(U);
	static Big Test(...);
	// note that ... has the lowest priority in function overloading
	// match, so only types that do not convert to U implicitely
	// will have to go to (...) version

	// following "function" is a must for classes having
	// private constructors. 
	static T MakeT();

public:
	enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
};



class A {
};

class B : public A {
};

void show_convertibility_test(void) {
	std::cout << "CONVERTIBILITY TEST" << std::endl;
	std::cout << "char => int ? " << Conversion<char, int>::exists << std::endl
		<< "char* => std::string ? " << Conversion<char*, std::string>::exists << std::endl
		<< "A* => B* ? " << Conversion<A*, B*>::exists << std::endl
		<< "B* => A* ? " << Conversion<B*, A*>::exists << std::endl;
}